package cn.iocoder.yudao.module.datasource.controller.admin.test;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.datasource.dal.dataobject.config.DynamicDataSourceConfigDO;
import cn.iocoder.yudao.module.datasource.service.config.DataSourceConfigService;
import cn.iocoder.yudao.module.datasource.service.config.DataSourceSwitchService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 动态数据源测试")
@RestController
@RequestMapping("/dynamic-datasource/test")
@Validated
@Slf4j
public class DynamicDataSourceTestController {

    @Resource
    private DataSourceSwitchService dataSourceSwitchService;
    
    @Resource(name = "dynamicDataSourceConfigService")
    private DataSourceConfigService dataSourceConfigService;

    @Autowired(required = false)
    private JdbcTemplate jdbcTemplate;

    @GetMapping("/test-current")
    @Operation(summary = "测试当前数据源连接")
    @PreAuthorize("@ss.hasPermission('datasource:config:query')")
    public CommonResult<String> testCurrentDataSource() {
        try {
            if (jdbcTemplate == null) {
                return success("JdbcTemplate 未初始化");
            }

            String currentDataSource = dataSourceSwitchService.getCurrentDataSource();
            jdbcTemplate.queryForObject("SELECT 1", Integer.class);

            return success("当前数据源连接正常: " + (currentDataSource == null ? "默认数据源" : currentDataSource));

        } catch (Exception e) {
            log.error("测试当前数据源失败", e);
            return success("数据源连接失败: " + e.getMessage());
        }
    }

    @PostMapping("/test-switch")
    @Operation(summary = "测试数据源切换功能")
    @PreAuthorize("@ss.hasPermission('datasource:config:switch')")
    public CommonResult<Map<String, Object>> testDataSourceSwitch(@RequestBody TestDataSourceSwitchReqVO reqVO) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            if (jdbcTemplate == null) {
                result.put("success", false);
                result.put("message", "JdbcTemplate 未初始化");
                return success(result);
            }

            // 获取当前数据源
            String originalDataSource = dataSourceSwitchService.getCurrentDataSource();
            result.put("originalDataSource", originalDataSource == null ? "默认数据源" : originalDataSource);

            // 切换到指定数据源
            if (reqVO.getDataSourceId() != null) {
                dataSourceSwitchService.switchTo(reqVO.getDataSourceId());
            } else {
                // 使用配置信息创建临时数据源
                DynamicDataSourceConfigDO config = new DynamicDataSourceConfigDO();
                config.setId(999999L); // 临时ID
                config.setName("测试数据源");
                config.setUrl(reqVO.getUrl());
                config.setUsername(reqVO.getUsername());
                config.setPassword(reqVO.getPassword());
                config.setType(reqVO.getType());
                config.setEnabled(true);
                
                dataSourceSwitchService.switchTo(config);
            }

            String currentDataSource = dataSourceSwitchService.getCurrentDataSource();
            result.put("switchedDataSource", currentDataSource);

            // 执行测试查询
            String sql = reqVO.getTestSql();
            if (sql == null || sql.trim().isEmpty()) {
                sql = "SELECT 1 as test_result"; // 默认测试SQL
            }

            List<Map<String, Object>> results = jdbcTemplate.queryForList(sql);
            result.put("queryResults", results);
            result.put("resultCount", results.size());

            // 恢复原数据源
            if (originalDataSource != null) {
                dataSourceSwitchService.switchTo(Long.parseLong(originalDataSource));
            } else {
                dataSourceSwitchService.switchToDefault();
            }

            result.put("success", true);
            result.put("message", "测试成功，查询到 " + results.size() + " 条记录");

        } catch (Exception e) {
            log.error("数据源切换测试失败", e);
            // 确保恢复到默认数据源
            dataSourceSwitchService.switchToDefault();
            
            result.put("success", false);
            result.put("message", "测试失败: " + e.getMessage());
        }
        
        return success(result);
    }

    @GetMapping("/create-sample-config")
    @Operation(summary = "创建示例数据源配置")
    @PreAuthorize("@ss.hasPermission('datasource:config:query')")
    public CommonResult<TestDataSourceSwitchReqVO> createSampleDataSourceConfig() {
        TestDataSourceSwitchReqVO config = new TestDataSourceSwitchReqVO();
        config.setUrl("jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true");
        config.setUsername("root");
        config.setPassword("123456");
        config.setType("MYSQL");
        config.setTestSql("SELECT COUNT(*) as table_count FROM information_schema.tables WHERE table_schema = DATABASE()");
        return success(config);
    }

    /**
     * 测试数据源切换请求VO
     */
    @Data
    public static class TestDataSourceSwitchReqVO {
        private Long dataSourceId; // 如果提供此参数，则使用已配置的数据源
        private String url = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true";
        private String username = "root";
        private String password = "123456";
        private String type = "MYSQL";
        private String testSql = "SELECT COUNT(*) as table_count FROM information_schema.tables WHERE table_schema = DATABASE()";
    }
}